package org.ejs.bean;

import java.util.LinkedList;
import java.util.NoSuchElementException;

import javax.annotation.PostConstruct;
import javax.ejb.AccessTimeout;
import javax.ejb.LocalBean;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.ejs.network.ServerAddress;


@Singleton(mappedName = "ServerManager")
@LocalBean
@Startup
@AccessTimeout(1500000000)
public class ServerManager implements ServerManagerRemote {

	private LinkedList<FileManagerRemote> ring;

	public ServerManager() {
	}

	@PostConstruct
	public void postConstruct() {
		ring = new LinkedList<FileManagerRemote>();
	}

	@Override
	public FileManagerRemote connect(ServerAddress serverAddress) {
		InitialContext ic = null;
		FileManagerRemote connect = null;
		FileManagerRemote old = ring.peek();
		if (old == null) {
			try {
				ic = new javax.naming.InitialContext(ClientTools.giveMeJndiProperties());
				connect  = (FileManagerRemote) ic.lookup("ejb:/efs/FileManager!org.ejs.bean.FileManagerRemote?stateful");
			} catch (NamingException e) {
				e.printStackTrace();
			}
			connect.setNext(connect);
			connect.setAddress(serverAddress);
			ring.add(connect);
			return connect;
		}
		try {
			ic = new javax.naming.InitialContext(ClientTools.giveMeJndiProperties());
			connect  = (FileManagerRemote) ic.lookup("ejb:/efs/FileManager!org.ejs.bean.FileManagerRemote?stateful");
		} catch (NamingException e) {
			e.printStackTrace();
		}
		connect.setNext(old);
		connect.setAddress(serverAddress);
		ring.getLast().setNext(connect);
		ring.addLast(connect);
		return connect;
	}

	@Override
	public void disconnect(ServerAddress remote) {
		int indexOf =-1;
		int realPrevious =0;
		int realNext=0;
		for(int i =0;i<ring.size();i++){
			if(ring.get(i).getAddress().equals(remote)){
				indexOf = i;
				break;
			}
		}
		if (indexOf == -1) {
			throw new NoSuchElementException("L'élément n'est pas présent. Mauvais");
		}
		if(indexOf == 0){
			realPrevious= ring.size();
		}
		else{
			realPrevious = (indexOf - 1) % ring.size();
		}
		if(indexOf == ring.size())
		{
			realNext=0;
		}
		else{
			realNext = (indexOf + 1) % ring.size();
		}
		ring.get(realPrevious).setNext(ring.get(realNext));
		ring.remove(indexOf);
	}
	
	
	public LinkedList<FileManagerRemote> getTest(){
		return ring;
	}
}
